package com.zhu.salesmanagement.views;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;

import com.dms2.salesmanagement.R;
import com.zhu.salesmanagement.utils.Util;

public class MySlideBar extends View {

    private boolean visibility;
    private String title = "";
    private float startX;
    private TextView tipsView;
    private Context mContext = null;

    public interface ChangeListener {
        void onChanged(int newValue, int oldValue);
    }

    public interface DisallowEventListener {
        void requestDisallowEvent(boolean disable);
    }

    public interface TipsViewMoveListener {
        void onMoved(int xPosition, int yPosition,boolean visibility);
    }

    public void setTitle(String title){
        this.title = title;
    }
    
    public void setTipsView(TextView tipsView){
        this.tipsView = tipsView;
    }

    static final private String TAG = "MySlideBar";

    static final private int BOLL_COUNT = 5;

    private ChangeListener mChangeListener;

    private ChangeListener mChangeEndListener;
    private DisallowEventListener mDisallowEventListener;

    private TipsViewMoveListener mTipsViewMovedLitener;

    private int mValue;

    private int mOldValue;

    private int mTouchX;

    private boolean mIsTouchDown;

    private Drawable mBoll;

    public MySlideBar(Context context) {
        super(context);
        mContext = context;
        init();
    }

    public MySlideBar(Context context, AttributeSet atts) {
        super(context, atts);
        mContext = context;
        init();
    }

    private void init() {
        this.setBackgroundResource(R.drawable.my_slide_bar_bolls);
        this.mBoll = this.getContext().getResources().getDrawable(R.drawable.my_slide_bar_boll);
    }

    public int getValue() {
        return this.mValue;
    }

    public void setValue(int val, boolean isEnd) {
        int oldVal = mValue;
        this.mValue = val;

        if (val != oldVal) {
            invalidate();
        }

        if (mChangeListener != null)
            mChangeListener.onChanged(val, oldVal);

        if (isEnd && mChangeEndListener != null)
            mChangeEndListener.onChanged(val, oldVal);
    }

    public void setChangeListener(ChangeListener changeListener) {
        this.mChangeListener = changeListener;
    }

    public void setDisallowEventListener(DisallowEventListener listener){
    	this.mDisallowEventListener = listener;
    }

    public void setChangeEndListener(ChangeListener changeListener) {
        this.mChangeEndListener = changeListener;
    }

    public void setTipsViewMoveListener(TipsViewMoveListener tipsViewMoveListener) {
        this.mTipsViewMovedLitener = tipsViewMoveListener;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int measuredWidth = getMeasuredWidth(widthMeasureSpec);
        int measuredHeight = getMeasuredHeight(heightMeasureSpec);
        setMeasuredDimension(measuredWidth, measuredHeight);
    }

    private int getMeasuredWidth(int measureSpec) {
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        int defaultSize = this.getBackground().getIntrinsicWidth();
        if (specMode == MeasureSpec.AT_MOST) {
            return Math.min(specSize, defaultSize);
        } else if (specMode == MeasureSpec.EXACTLY) {
            return specSize;
        } else {
            return defaultSize;
        }
    }

    private int getMeasuredHeight(int measureSpec) {
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        int defaultSize = this.getBackground().getIntrinsicHeight();
        if (specMode == MeasureSpec.AT_MOST) {
            return Math.min(specSize, defaultSize);
        } else if (specMode == MeasureSpec.EXACTLY) {
            return specSize;
        } else {
            return defaultSize;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int max = this.getWidth() - this.mBoll.getIntrinsicWidth();
        float bollX;
        if (mIsTouchDown) {
            bollX = Math.max(this.mTouchX, 0);
            bollX = Math.min(bollX, max);
        } else {
            bollX = ((float) mValue) / (BOLL_COUNT - 1) * max;
        }
        float bollY = (this.getHeight() - this.mBoll.getIntrinsicHeight()) / 2;
        int[] loc = new int[2];
        this.getLocationOnScreen(loc);

        if(mTipsViewMovedLitener != null){
        	mTipsViewMovedLitener.onMoved((int) bollX + loc[0] + this.mBoll.getIntrinsicWidth()/2, loc[1],visibility);
        }
        canvas.translate(bollX, bollY);

        mBoll.setBounds(0, 0, mBoll.getIntrinsicWidth(), mBoll.getIntrinsicHeight());
        mBoll.draw(canvas);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        int textColor = Color.rgb(57, 57, 57);
        paint.setColor(textColor);
        paint.setStyle(Style.FILL);
        paint.setTextSize(Util.spToPx(mContext, 12));
        canvas.drawText(title, this.mBoll.getIntrinsicHeight()/ 2, bollY+Util.dipToPx(mContext, 11), paint);
        canvas.translate(-bollX, -bollY);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:
            	if(mDisallowEventListener != null){
            		mDisallowEventListener.requestDisallowEvent(true);
            	}
                startX = event.getX();
                mIsTouchDown = true;
                mOldValue = mValue;
                mTouchX = (int) event.getX() - this.mBoll.getIntrinsicWidth()/2;
                setValue(getValueFromPixel(mTouchX), false);
                invalidate();
                return true;

            case MotionEvent.ACTION_MOVE:
                if (Math.abs(startX - event.getX()) > 4) {
                    mTouchX = (int) event.getX() - this.mBoll.getIntrinsicWidth()/2;
                    visibility = true;
                    setValue(getValueFromPixel(mTouchX), false);
                    invalidate();
                }
                return true;

            case MotionEvent.ACTION_OUTSIDE:
            case MotionEvent.ACTION_UP:
                visibility = false;
            case MotionEvent.ACTION_CANCEL:
                mTouchX = (int) event.getX() - this.mBoll.getIntrinsicWidth()/2;
                mIsTouchDown = false;
                setValue(getValueFromPixel(mTouchX), true);
                if(mDisallowEventListener != null){
            		mDisallowEventListener.requestDisallowEvent(false);
            	}
                invalidate();
                break;
        }
        return super.onTouchEvent(event);
    }

    private int getValueFromPixel(float x) {
        int val = (int) ((x+this.mBoll.getIntrinsicWidth()/2) / this.getWidth() * (BOLL_COUNT+1));
        if (val >= 2)
            --val;
        if (val < 0)
            return 0;
        if (val > (BOLL_COUNT - 1))
            return (BOLL_COUNT - 1);
        return val;
    }

}
